package com.jjzhk.common.beanConfig;

import org.I0Itec.zkclient.ZkClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ThreadLocalRandom;

/**
 * RegistryBean
 *
 * @author : JJZHK
 * @date : 2016-08-16
 * @comments :
 **/
public class RegistryBean implements DisposableBean,
        ApplicationContextAware, ApplicationListener<ApplicationEvent> {
    private Logger logger = LoggerFactory.getLogger(RegistryBean.class);
    private String address;
    private int port;
    private ZkClient zookeeper;
    private ApplicationContext ctx;

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }

    @Override
    public void destroy() throws Exception {

    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.ctx = applicationContext;
    }

    @Override
    public void onApplicationEvent(ApplicationEvent event) {
        if (event instanceof ContextRefreshedEvent)
        {
            zookeeper = new ZkClient(address + ":" + port, Constants.ZK_SESSION_TIMEOUT, Constants.ZK_CONNECTION_TIMEOUT);
        }
    }

    public void registryService(Map<String, Object> handlerMap, String serviceAddress)
    {
//        ZkClient zookeeper = new ZkClient(address + ":" + port, Constants.ZK_SESSION_TIMEOUT, Constants.ZK_CONNECTION_TIMEOUT);

        if (!zookeeper.exists(Constants.ZK_PATH))
        {
            zookeeper.createPersistent(Constants.ZK_PATH);
        }

        for(String serviceName : handlerMap.keySet())
        {
            String path = Constants.ZK_PATH + "/" + serviceName;
            if (!zookeeper.exists(path))
            {
                zookeeper.createPersistent(path);
            }

            String addressPath = path + "/address-";
            String addressNode = zookeeper.createEphemeralSequential(addressPath, serviceAddress);
        }
    }

    public synchronized String discoverService(String ServiceName)
    {
//        ZkClient zookeeper = new ZkClient(address + ":" + port, Constants.ZK_SESSION_TIMEOUT, Constants.ZK_CONNECTION_TIMEOUT);
        String serviceAddress = "";

        if (zookeeper.exists(Constants.ZK_PATH + "/" + ServiceName))
        {
            List<String> children = zookeeper.getChildren(Constants.ZK_PATH + "/" + ServiceName);

            int size = children.size();
            if (size == 1) {
                serviceAddress = children.get(0);
            } else {
                // 若存在多个地址，则随机获取一个地址
                serviceAddress = children.get(ThreadLocalRandom.current().nextInt(size));
            }

            serviceAddress = zookeeper.readData(Constants.ZK_PATH + "/" + ServiceName + "/" + serviceAddress);
            logger.info("Service address is : {}", serviceAddress);
        }

//        zookeeper.close();
        return serviceAddress;
    }

    public void close()
    {
        zookeeper.close();
    }
}
